home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / trojans / dcron / job.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-13  |  4.2 KB  |  220 lines

  1.  
  2. /*
  3.  * JOB.C
  4.  *
  5.  * Copyright 1994 Matthew Dillon (dillon@apollo.west.oic.com)
  6.  * May be distributed under the GNU General Public License
  7.  */
  8.  
  9. #include "defs.h"
  10.  
  11. Prototype void RunJob(CronFile *file, CronLine *line);
  12. Prototype void EndJob(CronFile *file, CronLine *line);
  13.  
  14. void
  15. RunJob(CronFile *file, CronLine *line)
  16. {
  17.     char mailFile[128];
  18.     int mailFd;
  19.  
  20.     line->cl_Pid = 0;
  21.     line->cl_MailFlag = 0;
  22.  
  23.     /*
  24.      * open mail file - owner root so nobody can screw with it.
  25.      */
  26.  
  27.     sprintf(mailFile, TMPDIR "/cron.%s.%d", file->cf_User, getpid());
  28.     mailFd = open(mailFile, O_CREAT|O_TRUNC|O_WRONLY|O_EXCL|O_APPEND, 0600);
  29.  
  30.     if (mailFd >= 0) {
  31.     line->cl_MailFlag = 1;
  32.     fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", 
  33.         file->cf_User,
  34.         line->cl_Shell
  35.     );
  36.     line->cl_MailPos = lseek(mailFd, 0, 1);
  37.     }
  38.  
  39.     /*
  40.      * Fork as the user in question and run program
  41.      */
  42.  
  43.     if ((line->cl_Pid = fork()) == 0) {
  44.     /*
  45.      * CHILD, FORK OK
  46.      */
  47.  
  48.     /*
  49.      * Change running state to the user in question
  50.      */
  51.  
  52.     if (ChangeUser(file->cf_User, 1) < 0)
  53.         return;
  54.  
  55.     if (DebugOpt)
  56.         log(5, "Child Running %s\n", line->cl_Shell);
  57.  
  58.     /*
  59.      * Setup close-on-exec descriptor in case exec fails
  60.      */
  61.  
  62.     dup2(2, 8);
  63.     fcntl(8, F_SETFD, 1);
  64.     fclose(stderr);
  65.  
  66.     /*
  67.      * stdin is already /dev/null, setup stdout and stderr
  68.      */
  69.  
  70.     if (mailFd >= 0) {
  71.         dup2(mailFd, 1);
  72.         dup2(mailFd, 2);
  73.         close(mailFd);
  74.     } else {
  75.         logfd(8, "unable to create mail file user %s file %s, output to /dev/null\n",
  76.             file->cf_User,
  77.             mailFile
  78.         );
  79.     }
  80.     execl("/bin/sh", "/bin/sh", "-c", line->cl_Shell, NULL, NULL);
  81.     logfd(8, "unable to exec, user %s cmd /bin/sh -c %s\n", 
  82.         file->cf_User,
  83.         line->cl_Shell
  84.     );
  85.     fdprintf(1, "Exec failed: /bin/sh -c %s\n", line->cl_Shell);
  86.     exit(0);
  87.     } else if (line->cl_Pid < 0) {
  88.     /*
  89.      * PARENT, FORK FAILED
  90.      */
  91.         log9("couldn't fork, user %s\n", file->cf_User);
  92.         line->cl_Pid = 0;
  93.         remove(mailFile);
  94.     } else {
  95.     /*
  96.      * PARENT, FORK SUCCESS
  97.      *
  98.      * rename mail-file based on pid of process
  99.      */
  100.     char mailFile2[128];
  101.  
  102.     sprintf(mailFile2, TMPDIR "/cron.%s.%d", file->cf_User, line->cl_Pid);
  103.     rename(mailFile, mailFile2);
  104.     }
  105.  
  106.     /*
  107.      * Close the mail file descriptor.. we can't just leave it open in
  108.      * a structure, closing it later, because we might run out of descriptors
  109.      */
  110.  
  111.     if (mailFd >= 0)
  112.         close(mailFd);
  113. }
  114.  
  115. /*
  116.  * EndJob - called when job terminates and when mail terminates
  117.  */
  118.  
  119. void
  120. EndJob(CronFile *file, CronLine *line)
  121. {
  122.     int mailFd;
  123.     char mailFile[128];
  124.     struct stat sbuf;
  125.  
  126.     /*
  127.      * No job
  128.      */
  129.  
  130.     if (line->cl_Pid <= 0) {
  131.         line->cl_Pid = 0;
  132.         return;
  133.     }
  134.  
  135.     /*
  136.      * End of job and no mail file
  137.      * End of sendmail job
  138.      */
  139.  
  140.     sprintf(mailFile, TMPDIR "/cron.%s.%d", file->cf_User, line->cl_Pid);
  141.     line->cl_Pid = 0;
  142.  
  143.     if (line->cl_MailFlag != 1)
  144.         return;
  145.  
  146.     line->cl_MailFlag = 0;
  147.  
  148.     /*
  149.      * End of primary job - check for mail file.  If size has increased and
  150.      * the file is still valid, we sendmail it.
  151.      */
  152.  
  153.     mailFd = open(mailFile, O_RDONLY);
  154.     remove(mailFile);
  155.     if (mailFd < 0) {
  156.         return;
  157.     }
  158.     if (fstat(mailFd, &sbuf) < 0 || 
  159.         sbuf.st_uid != DaemonUid || 
  160.         sbuf.st_nlink != 0 ||
  161.         sbuf.st_size == line->cl_MailPos ||
  162.         !S_ISREG(sbuf.st_mode)
  163.     ) {
  164.         close(mailFd);
  165.          return;
  166.     }
  167.  
  168.     if ((line->cl_Pid = fork()) == 0) {
  169.     /*
  170.      * CHILD, FORK OK
  171.      */
  172.  
  173.     /*
  174.      * change user id - no way in hell security can be compromised
  175.      * by the mailing and we already verified the mail file.
  176.      */
  177.  
  178.     if (ChangeUser(file->cf_User, 1) < 0)
  179.         exit(0);
  180.  
  181.     /*
  182.      * create close-on-exec log descriptor in case exec fails
  183.      */
  184.  
  185.     dup2(2, 8);
  186.     fcntl(8, F_SETFD, 1);
  187.  
  188.     fclose(stderr);
  189.  
  190.     /*
  191.      * run sendmail with mail file as standard input, only if
  192.      * mail file exists!
  193.      */
  194.  
  195.     dup2(mailFd, 0);
  196.     dup2(1, 2);
  197.     close(mailFd);
  198.  
  199.     execl(SENDMAIL, SENDMAIL, SENDMAIL_ARGS, NULL, NULL);
  200.     logfd(8, "unable to exec %s %s, user %s, output to sink null", 
  201.         SENDMAIL,
  202.         SENDMAIL_ARGS,
  203.         file->cf_User
  204.     );
  205.     exit(0);
  206.     } else if (line->cl_Pid < 0) {
  207.     /*
  208.      * PARENT, FORK FAILED
  209.      */
  210.     log9("unable to fork, user %s", file->cf_User);
  211.     line->cl_Pid = 0;
  212.     } else {
  213.     /*
  214.      * PARENT, FORK OK
  215.      */
  216.     }
  217.     close(mailFd);
  218. }
  219.  
  220.